<?php

namespace app\sms\controller;

use app\api\controller\Common;
use \app\check\controller\Check;
use app\common\cachemodel\AppConfig;
use app\common\lib\exception\ApiException;
use app\common\lib\Util;
use app\common\model\User;
use think\Db;

/**
 * 接口调用验证
 */
class Sms extends Check
{
    private $accountSid = '';//主帐号,对应开官网发者主账号下的 ACCOUNT SID
    private $accountToken = '';//主帐号令牌,对应官网开发者主账号下的 AUTH TOKEN
    private $appId = '';//应用Id，在官网应用列表中点击应用，对应应用详情中的APP ID //在开发调试的时候，可以使用官网自动为您分配的测试Demo的APP ID
    private $serverIP = '';//请求地址 沙盒环境（用于应用开发调试）：sandboxapp.cloopen.com 生产环境（用户应用上线使用）：app.cloopen.com
    private $serverPort = '';//请求端口，生产环境和沙盒环境一致
    private $softVersion = '';//REST版本号，在官网文档REST介绍中获得。
    private $Batch;  //时间戳
    private $BodyType = "json";// 包体格式，可填值：json 、xml

    protected function _initialize()
    {
        if (!defined('IS_ACCESS_TOKEN_CHECKED'))
        {
            if (isset(request()->header()['sign']))
            {
                (new Common())->checkRequestAuth();
            } else
            {
                if ($this->func == 'CheckAccessTokenSafe')
                {
                    $accessTokenStatusSafe = $this->CheckAccessTokenSafe();

                    if ($accessTokenStatusSafe['code'] != 200)
                    {
                        echo json_encode($accessTokenStatusSafe);
                        exit;
                    }
                }
                if ($this->func == 'check')
                {
                    $check = $this->check();

                    if ($check['code'] != 200)
                    {
                        echo json_encode($check);
                        exit;
                    }
                }
            }
        }

//        parent::_initialize();// 不需要登录
        $this->accountSid = config('sms_account_sid');
        $this->accountToken = config('sms_account_token');
        $this->appId = config('sms_appid');
        $this->serverIP = config('sms_server_ip');
        $this->serverPort = config('sms_server_port');
        $this->softVersion = config('sms_soft_version');
        $this->Batch = date("YmdHis");
//        $this->Handle = fopen($this->Filename, 'a');
    }

    /**
     * 获取短信验证码
     */
    public function get_code()
    {
        $tel = input('tel/s');

        if (!preg_match("/^1[3456789]{1}\d{9}$/", $tel))
        {
            return show(config('code.error'), '手机号错误');
        }

        $time = time();// 当前时间  有效时间暂定为十分钟 600s

        $expire = 600;

        $ip = request()->ip();

        try
        {
            $data = Db::table('app_tel_login')->where(['tel' => "$tel", 'expire_time' => ['>', $time]])->find();
        }
        catch (\Exception $e)
        {
            $data = [];
        }
        // 十分钟内无已有验证码
        if (empty($data))
        {
            $code = mt_rand(100000, 999999);// 六位验证码

            $expire_time = $time + $expire;

            if (!$id = Db::table('app_tel_login')->insertGetId([
                'tel' => "$tel",
                'create_time' => $time,
                'expire_time' => $expire_time,
                'code' => $code,
            ]))
            {
                return show(config('code.error'), '发送失败');
            }
        } else
        {
            $code = $data['code'];
        }

        $alidayu = (new AppConfig())->configInfo('alidayu');
        $result = sendSms($tel, ['code' => $code], $alidayu['login_code']);

        if (!empty($result) && $result['Code'] != 'OK')
        {
            return json(['code' => 10202, 'msg' => $result['Message']]);
        } else
        {

            // 记录短信日志
            model('log')->save([
                'tel' => "$tel",
                'ip' => $ip,
                'create_time' => $time,
                'type' => 1,
            ]);

            return show(config('code.success'), '短信发送成功');
        }
    }

    /**
     * 短信登录
     * @throws ApiException
     */
    public function check_code()
    {
        $tel = input('tel/s');
        $code = input('code/d');

        if (!$tel || !$code || strlen($code) != 6)
        {
            return show(config('code.error'), '手机号或验证码错误');
        }
        if (!preg_match("/^1[3456789]{1}\d{9}$/", $tel))
        {
            return show(config('code.error'), '手机号格式错误');
        }

        $ip = $this->request->ip();// 访问IP地址

        $time = $this->request->time();// 当前时间  有效时间暂定为十分钟 600s

        $UserModel = new User();

        if (
            ($tel == '18511747279' && $code == '666666')
            || ($tel == '13170924253' && $code == '666666')
            || ($tel == '18801204521' && $code == '666666')
            || ($tel == '15613538393' && $code == '111111')
            || ($tel == '17600102924' && $code == '666666')
            || ($tel == '15234800287' && $code == '666666')
            || ($tel == '18356978638' && $code == '666666')
            || ($tel == '18511696867' && $code == '666666')
            || ($tel == '13488716008' && $code == '666666')
            || ($tel == '17333657763' && $code == '666666')
            || ($tel == '13488716008' && $code == '666666')
            || ($tel == '15601383717' && $code == '666666')
        )
        {
            try
            {
                $user = $UserModel
                    ->field('id,uen,tel,nickname,avatar,forbidden,email,is_first_login,uc_id,has_self_recode')
                    ->where('tel', "$tel")
                    ->find();
            }
            catch (\Exception $e)
            {
                $user = [];
            }

            if (empty($user) || $user === null)
            {
                $user = [
                    'uen' => substr(md5(microtime() . mt_rand(0, 1000000) . uniqid()), 0, 12),
                    'nickname' => preg_replace('/(1[3589]{1}[0-9])[0-9]{4}([0-9]{4})/i', '$1****$2', $tel),
                    'tel' => "$tel",
                    'tel_status' => 1,
                    'reg_time' => $time,
                    'reg_ip' => $ip,
                    'last_login' => $time,
                    'last_ip' => $ip,
                    'last_active' => $time,
                    'is_first_login' => 1,// 首次登陆标记
                    'uc_id' => md5($tel . microtime()),
                    'channel' => Util::getChannelId()
                ];
                if (!$user['id'] = $UserModel->insertGetId($user))
                {
                    return show(config('code.error'), '注册失败');
                }
                $user['email'] = null;
                $user['avatar'] = null;
                $user['forbidden'] = 0;
                $user['has_self_recode'] = 0;
                // 用户星盘配置初始化 TODO 使用新版配置
                $set = new \app\user\controller\Astroset();
                $set->init($user['id']);
            } else
            {
                if ($user['forbidden'] == 1)
                {
                    return show(config('code.error'), '禁止登录');
                }
                // 更新用户昵称为手机号
                if (!$user['nickname'])
                {
                    try
                    {
                        $UserModel->where('tel', "$tel")->update(['nickname' => preg_replace('/(1[3589]{1}[0-9])[0-9]{4}([0-9]{4})/i', '$1****$2', $tel),]);
                    }
                    catch (\Exception $e)
                    {
                        \think\Log::write('登陆时修改用户昵称失败' . $e->getMessage(), 'error', true);
                    }
                }
            }
            // 记录登陆日志
            Db::table('app_login_log')->insertGetId([
                'uid' => $user['id'],
                'login_time' => $time,
                'login_type' => 4,
                'login_ip' => $ip,
            ]);

            return show(config('code.success'), '登录成功', $user);
        } else
        {
            try
            {
                $data = Db::table('app_tel_login')->where(['tel' => "$tel", 'code' => "$code"])->find();
            }
            catch (\Exception $e)
            {
                $data = [];
            }
            // 登陆失败
            if (empty($data))
            {
                return show(config('code.error'), '验证码错误');
            } // 验证成功
            else
            {
                if ($data['expire_time'] < $time)
                {
                    return show(config('code.error'), '验证码已过期');
                }

                try
                {
                    $user = $UserModel
                        ->field('id,tel,nickname,avatar,forbidden,email,is_first_login,uc_id,has_self_recode')
                        ->where('tel', "$tel")
                        ->find();
                }
                catch (\Exception $e)
                {
                    $user = [];
                }

//                登陆成功修改用户表首次登的状态
                if (empty($user) || $user === null)
                {
                    $user = [
                        'nickname' => preg_replace('/(1[3589]{1}[0-9])[0-9]{4}([0-9]{4})/i', '$1****$2', $tel),
                        'tel' => "$tel",
                        'tel_status' => 1,
                        'reg_time' => $time,
                        'reg_ip' => $ip,
                        'last_login' => $time,
                        'last_ip' => $ip,
                        'last_active' => $time,
                        'is_first_login' => 1,// 首次登陆标记
                        'uc_id' => md5($tel . $time),
                        'channel' => Util::getChannelId()
                    ];
                    if (!$user['id'] = $UserModel->insertGetId($user))
                    {
                        return show(config('code.error'), '注册失败');
                    }
                    $user['email'] = null;
                    $user['avatar'] = null;
                    $user['forbidden'] = 0;
                    $user['has_self_recode'] = 0;
                    // 用户星盘配置初始化 TODO 使用新版星盘配置
                    $set = new \app\user\controller\Astroset();
                    $set->init($user['id']);
                } else
                {
                    if ($user['forbidden'] == 1)
                    {
                        return show(config('code.error'), '禁止登录');
                    }
                    if (!$user['nickname'])
                    {
                        try
                        {
                            $UserModel->where('tel', "$tel")
                                ->update(['nickname' => preg_replace('/(1[3589]{1}[0-9])[0-9]{4}([0-9]{4})/i', '$1****$2', $tel),]);
                        }
                        catch (\Exception $e)
                        {
                            \think\Log::write('登陆时修改用户昵称失败' . $e->getMessage(), 'error', true);
                        }
                    }
                }

                //        将用户头像和档案头像统一
                $map = ['uid' => $user['id'], 'isself' => 1];
                try
                {
                    $rea = Db::table('wechat_backup_07_18_14_43_00.app_recode')->field('avatar')->where($map)->find();
                }
                catch (\Exception $e)
                {
                    $rea = [];
                }
                if ($rea)
                {
                    if (strcmp($rea['avatar'], $user['avatar']) !== 0)
                    {
                        try
                        {
                            $UserModel->where('id', $user['id'])->update(['avatar' => $rea['avatar']]);
                        }
                        catch (\Exception $e)
                        {
                            \think\Log::write('登陆时修改用户头像失败' . $e->getMessage(), 'error', true);
                        }
                    }
                }

                $UserModel->check_uen($user);

                // 记录登陆日志
                Db::table('app_login_log')->insertGetId([
                    'uid' => $user['id'],
                    'login_time' => $time,
                    'login_type' => 4,
                    'login_ip' => $ip,
                ]);

                return show(config('code.success'), '登录成功', $user);
            }
        }
    }

    /**
     * 发送模板短信
     * @param to 短信接收彿手机号码集合,用英文逗号分开
     * @param datas 内容数据
     * @param $tempId 模板Id
     */
    protected function sendTemplateSMS($to, $datas, $tempId)
    {
        //主帐号鉴权信息验证，对必选参数进行判空。
        $auth = $this->accAuth();
        if ($auth != "")
        {
            return $auth;
        }
        // 拼接请求包体
        if ($this->BodyType == "json")
        {
            $data = "";
            for ($i = 0; $i < count($datas); $i++)
            {
                $data = $data . "'" . $datas[$i] . "',";
            }
            $body = "{'to':'$to','templateId':'$tempId','appId':'$this->appId','datas':[" . $data . "]}";
        } else
        {
            $data = "";
            for ($i = 0; $i < count($datas); $i++)
            {
                $data .= "<data>" . $datas[$i] . "</data>";
            }
            $body = "<TemplateSMS>
                    <to>$to</to> 
                    <appId>$this->appId</appId>
                    <templateId>$tempId</templateId>
                    <datas>" . $data . "</datas>
                  </TemplateSMS>";
        }
//        $this->showlog("request body = ".$body);
        // 大写的sig参数
        $sig = strtoupper(md5($this->accountSid . $this->accountToken . $this->Batch));
        // 生成请求URL
        $url = "https://$this->serverIP:$this->serverPort/$this->softVersion/Accounts/$this->accountSid/SMS/TemplateSMS?sig=$sig";
//        $this->showlog("request url = ".$url);
        // 生成授权：主帐户Id + 英文冒号 + 时间戳。
        $authen = base64_encode($this->accountSid . ":" . $this->Batch);
        // 生成包头
        $header = ["Accept:application/$this->BodyType", "Content-Type:application/$this->BodyType;charset=utf-8", "Authorization:$authen"];
        // 发送请求
        $result = curl_post($url, $body, $header, 'json');
//        $this->showlog("response body = ".$result);
        if ($this->BodyType == "json")
        {//JSON格式
            $datas = json_decode($result);
        } else
        { //xml格式
            $datas = simplexml_load_string(trim($result, " \t\n\r"));
        }
        //  if($datas == FALSE){
//            $datas = new stdClass();
//            $datas->statusCode = '172003';
//            $datas->statusMsg = '返回包体错误';
//        }
        //重新装填数据
        if ($datas->statusCode == 0)
        {
            if ($this->BodyType == "json")
            {
                $datas->TemplateSMS = $datas->templateSMS;
                unset($datas->templateSMS);
            }
        }

        return $datas;
    }

    /**
     * 主帐号鉴权
     */
    protected function accAuth()
    {
        if ($this->serverIP == "")
        {
            $data = new stdClass();// 创建空对象
            $data->statusCode = '11001';
            $data->statusMsg = 'IP为空';
            return $data;
        }
        if ($this->serverPort <= 0)
        {
            $data = new stdClass();
            $data->statusCode = '11002';
            $data->statusMsg = '端口错误（小于等于0）';
            return $data;
        }
        if ($this->softVersion == "")
        {
            $data = new stdClass();
            $data->statusCode = '11003';
            $data->statusMsg = '版本号为空';
            return $data;
        }
        if ($this->accountSid == "")
        {
            $data = new stdClass();
            $data->statusCode = '11004';
            $data->statusMsg = '主帐号为空';
            return $data;
        }
        if ($this->accountToken == "")
        {
            $data = new stdClass();
            $data->statusCode = '11005';
            $data->statusMsg = '主帐号令牌为空';
            return $data;
        }
        if ($this->appId == "")
        {
            $data = new stdClass();
            $data->statusCode = '11006';
            $data->statusMsg = '应用ID为空';
            return $data;
        }
    }
}
